package base.interceptor;

import base.exception.LogicException;
import base.utils.UuidUtils;
import base.BaseReturn;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

/**
 * @author liujia
 */
@Aspect
public class LogicInterceptor {
    private static Logger logger = LoggerFactory.getLogger(LogicInterceptor.class);
    private static final String POINTCUT = "execution(* base.BaseLogic+.*(..))";
    private static final String TRACE_ID_KEY = "traceId";

    @Pointcut(POINTCUT)
    public void logicMethods() {
    }

    @Before(value = "logicMethods()")
    public void doBefore(JoinPoint joinPoint) throws Exception {
        Object[] args = joinPoint.getArgs();
        logger.info(String.format("--->>>开始，调用类：%s,方法：%s",
                joinPoint.getTarget().getClass(), joinPoint.getSignature().getName()));
        for (int i = 0; i < args.length; i++) {
            logger.info(String.format("--- >>传入参数:%s", args[i]));
        }
    }

    @AfterReturning(value = "logicMethods()", returning = "result")
    public void doAfter(JoinPoint joinPoint, Object result) {
        logger.info(String.format("<<<---结束，调用类：%s,方法：%s,结果：%s",
                joinPoint.getTarget().getClass(), joinPoint.getSignature().getName(), result));

        MDC.remove(TRACE_ID_KEY);
    }

    /**
     * 添加traceId, 捕获异常并处理
     *
     * @param proceedingJoinPoint
     * @return Object
     * @throws Throwable
     */
    @Around(value = "logicMethods()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        // 生成跟踪ID
        String traceId = MDC.get(TRACE_ID_KEY);
        if (StringUtils.isBlank(traceId)) {
            traceId = UuidUtils.randomUUID().toString();
            MDC.put(TRACE_ID_KEY, traceId);
        }

        BaseReturn baseRet = null;

        Object r = null;
        try {
            r = proceedingJoinPoint.proceed();
        } catch (LogicException be) {
            logger.error(String.format("业务异常:异常编号:%s，异常信息:%s",
                    be.getCode(), be.getMessage()), be);
            return new BaseReturn(be.getCode(), be.getMessage());
        } catch (Exception e) {
            logger.error(String.format("系统异常:异常编号:%s,异常消息:%s",
                    BaseReturn.ERROR,BaseReturn.ERROR_STR), e);
            return new BaseReturn(BaseReturn.ERROR, e.getMessage(), e);
        }
        return r;
    }

    /**
     * @Description 异常通知
     * @param jp
     * @param e
     */
    @AfterThrowing(value = "logicMethods()", throwing = "e")
    public void doThrow(JoinPoint jp, LogicException e) {
    }
}
